#include "Poco/Net/SecureStreamSocket.h"
#include "Poco/Net/SocketAddress.h"

#include "Poco/Net/TCPServer.h"
#include "Poco/Net/TCPServerConnection.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Net/TCPServerParams.h"
#include "Poco/Net/SecureStreamSocket.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Thread.h"
#include "Poco/Util/Application.h"
#include <iostream>
#include "assert.h"

using Poco::Net::TCPServer;
using Poco::Net::TCPServerConnection;
using Poco::Net::TCPServerConnectionFactory;
using Poco::Net::TCPServerConnectionFactoryImpl;
using Poco::Net::TCPServerParams;
using Poco::Net::StreamSocket;
using Poco::Net::SecureStreamSocket;
using Poco::Net::SecureServerSocket;
using Poco::Net::SocketAddress;
using Poco::Thread;
using namespace Poco::Util;

using namespace Poco;
using namespace Poco::Net;


class EchoConnection: public TCPServerConnection
{
public:
    EchoConnection(const StreamSocket& s): TCPServerConnection(s)
    {
    }

    void run()
    {
        StreamSocket& ss = socket();
        try
        {
            char buffer[256];
            int n = ss.receiveBytes(buffer, sizeof(buffer));
            while (n > 0)
            {
                ss.sendBytes(buffer, n);
                n = ss.receiveBytes(buffer, sizeof(buffer));
            }
        }
        catch (Poco::Exception& exc)
        {
            std::cerr << "EchoConnection: " << exc.displayText() << std::endl;
        }
    }
};




void testOneConnection()
{
    SecureServerSocket svs(0);
    TCPServer srv(new TCPServerConnectionFactoryImpl<EchoConnection>(), svs);
    srv.start();
    assert (srv.currentConnections() == 0);
    assert (srv.currentThreads() == 0);
    assert (srv.queuedConnections() == 0);
    assert (srv.totalConnections() == 0);

    SocketAddress sa("localhost", svs.address().port());
    SecureStreamSocket ss1(sa);
    std::string data("hello, world");
    ss1.sendBytes(data.data(), (int) data.size());
    char buffer[256];
    int n = ss1.receiveBytes(buffer, sizeof(buffer));
    assert (n > 0);
    assert (std::string(buffer, n) == data);
    assert (srv.currentConnections() == 1);
    assert (srv.currentThreads() == 1);
    assert (srv.queuedConnections() == 0);
    assert (srv.totalConnections() == 1);
    ss1.close();
    Thread::sleep(300);
    assert (srv.currentConnections() == 0);
}

int main3()
{
    Application* p_app = new Application;
    p_app->loadConfiguration("c:/test/test_case.xml");

    testOneConnection();

    return 0;
}


int main2()
{
    Application* p_app = new Application;
    p_app->loadConfiguration("c:/test/test_case.xml");

    Poco::Net::SocketAddress sa("www.google.com",443);

    Poco::Net::SecureStreamSocket ssskt;
   // ssskt.setPeerHostName("www.google.com");

   // ssskt.completeHandshake();


    return 0;
}

int main()
{
    Application* p_app = new Application;
    p_app->loadConfiguration("c:/test/test_case.xml");
    SocketAddress sa("localhost", 4433);
    StreamSocket st;
    st.connect(sa);

    SecureStreamSocket sst = SecureStreamSocket::attach(st);



    return 0;
}